/* sys_cmd.c */
#include <sys/prctl.h>
#include "sys_cmd.h"

cmd_desc_t cmd_map[] = {
    [HOST_CMD_TEST1 - HOST_CMD_MIN] = {0, 0, process_test1},
    [HOST_CMD_TEST2 - HOST_CMD_MIN] = {0, 0, process_test2},
    [SMART_HOST_CMD_TEST1 - SMART_HOST_CMD_MIN + 100] = {0, 0, process_smart_test1},
    [HOST_CMD_EXIT - HOST_CMD_MIN] = {0, 0, process_exit}
};

int func_pthread_name_set(char *pthread_name)
{
    int ret = 0;
    char name[16] = {0};

    snprintf(name, sizeof(name), "%s", pthread_name);

    ret = prctl(PR_SET_NAME, name);
    if(ret != 0)
    {
        ERROR("pthread_name_set failed: %s", strerror(ret));
    }
    return ret;
}
// 线程创建封装函数
int func_pthread_create(pthread_t *tid, const thread_attr_t *config)
{
    int ret = 0;
    pthread_attr_t attr = {0};

    // 初始化线程属性
    if ((ret = pthread_attr_init(&attr)) != 0)
    {
        ERROR("pthread_attr_init failed: %s", strerror(ret));
        return ret;
    }

    // 设置分离状态（默认创建分离线程）
    if ((ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) != 0)
    {
        ERROR("pthread_attr_setdetachstate failed: %s", strerror(ret));
        pthread_attr_destroy(&attr);
        return ret;
    }

    // 创建线程
    if ((ret = pthread_create(tid, &attr, config->thread_func, config->arg)) != 0)
    {
        ERROR("pthread_create failed: %s", strerror(ret));
        pthread_attr_destroy(&attr);
        return ret;
    }

    pthread_attr_destroy(&attr);
    return 0;
}

void *command_processor(void *arg)
{
    unsigned int cmd_num = 0;
    unsigned int cmd_idx = 0;
    
    pthread_para_t *pthread_para_data = (pthread_para_t *)arg;
    struct sembuf sops = {.sem_num = 0, .sem_op = -1, .sem_flg = 0};

    func_pthread_name_set("cmd_process");

    // 获取命令总个数
    cmd_num = sizeof(cmd_map) / sizeof(cmd_map[0]);
    while (atomic_load(&pthread_para_data->running))
    {
        if (semop(pthread_para_data->sem_id, &sops, 1) == -1)
        {
            if (errno == EINTR)
                continue;
            ERROR("semop wait error: %d", errno);
            break;
        }

        DEBUG("Processing command: %d", pthread_para_data->shm_ptr->cmd_id);

        cmd_idx = (pthread_para_data->shm_ptr->cmd_id >= SMART_HOST_CMD_MIN)
                        ? (pthread_para_data->shm_ptr->cmd_id - SMART_HOST_CMD_MIN + 100)
                        : (pthread_para_data->shm_ptr->cmd_id - HOST_CMD_MIN);

        if (cmd_idx < cmd_num)
        {
            if (cmd_map[cmd_idx].pFunc)
            {
                cmd_map[cmd_idx].pFunc(pthread_para_data->shm_ptr->param, pthread_para_data->shm_ptr->value);
                if (pthread_para_data->shm_ptr->cmd_id == HOST_CMD_EXIT)
                {
                    atomic_store(&pthread_para_data->running, FALSE);
                }
            }
        }
        else
        {
            ERROR("Invalid command index: %d", cmd_idx);
        }
    }
    return NULL;
}

int main(int argc, char **argv)
{
    int cnt = 0;
    // 初始化共享内存
    int shmid = shmget(SHM_KEY, sizeof(shm_buf_data_t), IPC_CREAT | 0666);
    if (shmid == -1)
    {
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    shm_buf_data_t *shm_data = (shm_buf_data_t *)shmat(shmid, NULL, 0);
    if (shm_data == (void *)-1)
    {
        perror("shmat");
        exit(EXIT_FAILURE);
    }
    DEBUG("Shared memory initialized at: %p", shm_data);

    // 初始化信号量
    int semid = semget(SEM_KEY, 1, IPC_CREAT | 0666);
    if (semid == -1)
    {
        perror("semget");
        exit(EXIT_FAILURE);
    }

    union semun sem_arg = {.val = 0};
    if (semctl(semid, 0, SETVAL, sem_arg) == -1)
    {
        perror("semctl init");
        exit(EXIT_FAILURE);
    }

    // 初始化线程上下文
    pthread_para_t pthread_para_data = {0};
    pthread_para_data.shm_ptr = shm_data;
    pthread_para_data.sem_id = semid;
    pthread_para_data.running = TRUE;

    thread_attr_t processor_cfg = {0};
    processor_cfg.thread_func = command_processor;
    processor_cfg.arg = &pthread_para_data;
    processor_cfg.name = "cmd_processor";

    pthread_t processor_tid = 0;
    if (func_pthread_create(&processor_tid, &processor_cfg) != 0)
    {
        exit(EXIT_FAILURE);
    }

    func_pthread_name_set("main");
    // 主线程监控循环
    while (atomic_load(&pthread_para_data.running))
    {
        sleep(1);
        cnt++;
        if(cnt > 10)
        {
            cnt = 0;
            DEBUG("Main thread heartbeat!");
        }
    }

    // 资源清理
    DEBUG("Cleaning system resources");
    shmdt(shm_data);
    shmctl(shmid, IPC_RMID, NULL);
    semctl(semid, 0, IPC_RMID);

    DEBUG("System shutdown completed");
    return 0;
}


cmd_process_func(process_test1)
{
    printf("[PROCESSOR] Test1 received - param: %d, value: %d\n", param, value);
    return 0;
}

cmd_process_func(process_test2)
{
    printf("[PROCESSOR] Test2 received - param: %d, value: %d\n", param, value);
    return 0;
}

cmd_process_func(process_smart_test1)
{
    printf("[PROCESSOR] SmartTest1 received - param: %d, value: %d\n", param, value);
    return 0;
}

cmd_process_func(process_exit)
{
    DEBUG("Initiating shutdown sequence... param: %d, value: %d\n", param, value);
    return 0;
}
